using System;
using System.Text;
using System.Windows.Forms;

namespace Glpt.Common
{
    /// <summary>
    /// 常用功能类
    /// </summary>
    public class Funcs
    {
        /// <summary>
        /// 当前的执行目录
        /// </summary>
        public static string AppPath = "";
        /// <summary>
        /// 数据存放的路径
        /// </summary>
        public static string DataPath = "";
        /// <summary>
        /// 界面语言
        /// </summary>
        public static int Conversion = 256;
        private static Object task_Lock = new Object();
        private const string ErrFileName = "err.log";   //记录系统错误日志文件

        /// <summary>
        /// 显示提示框
        /// </summary>
        /// <param name="strTip">要提示的信息</param>
        public static void ShowTip(String strTip)
        {
            MessageBox.Show(StrConv(strTip), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private static string ReplaceMSG(string val)
        {
            string str = val;
            int idx1 = str.IndexOf("ORA-20001:");
            int idx2 = str.IndexOf("ORA-06512:");
            if (idx1 >= 0 && idx2 > idx1)
                str = str.Substring(idx1 + 10, idx2 - idx1 - 11);
            idx1 = str.IndexOf("--->");
            if (idx1 >= 0)
                str = str.Substring(idx1 + 4).Trim();
            return str;
        }

        /// <summary>
        /// 显示错误提示框
        /// </summary>
        /// <param name="strTip">要提示的信息</param>
        public static void ShowError(String strTip)
        {
            MessageBox.Show(StrConv(ReplaceMSG(strTip)), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        /// <summary>
        /// 显示询问框
        /// </summary>
        /// <param name="strTip">要询问的信息</param>
        public static DialogResult ShowQuestion(String strTip)
        {
            return ShowQuestion(strTip, MessageBoxButtons.YesNo);
        }

        /// <summary>
        /// 显示询问框
        /// </summary>
        /// <param name="strTip">要询问的信息</param>
        /// <param name="buttons">可指定在消息框中显示哪些按钮</param>
        public static DialogResult ShowQuestion(String strTip, MessageBoxButtons buttons)
        {
            return MessageBox.Show(StrConv(strTip), StrConv("询问"), buttons, MessageBoxIcon.Question);
        }

        /// <summary>
        /// 显示错误提示框
        /// </summary>
        /// <param name="ex">错误对象</param>
        public static void ShowError(Exception ex)
        {
            try
            {
                WriteErrorLog(ex);
                ShowError(ReplaceMSG(ex.Message));
            }
            catch
            {
                ShowError(ex.Message + "(记录日志失败)");
            }
        }

        /// <summary>
        /// 记录错误信息
        /// </summary>
        /// <param name="ex">错误对象</param>
        public static void WriteErrorLog(Exception ex)
        {
            StringBuilder sbuf = new StringBuilder();
            sbuf.Append(DateTime.Now.ToString() + "错误信息：");
            sbuf.AppendLine(ex.Message);
            AppendLog(ex, sbuf);
            lock (task_Lock)
            {
                System.IO.File.AppendAllText(AppPath + ErrFileName, sbuf.ToString());
            }
        }

        private static void AppendLog(Exception ex, StringBuilder sbuf)
        {
            if (ex.InnerException != null)
                AppendLog(ex.InnerException, sbuf);
            sbuf.AppendLine(ex.StackTrace);
        }

        /// <summary>
        /// 判断是否是整型
        /// </summary>
        /// <param name="val">包含要转换的数字的字符串</param>
        /// <returns>是否是整型</returns>
        public static bool IsInt(string val)
        {
            long ret = 0;
            return long.TryParse(val, out ret);
        }

        /// <summary>
        /// 判断是否是数值型
        /// </summary>
        /// <param name="val">包含数值字符串</param>
        /// <returns>是否</returns>
        public static bool IsNumber(string val)
        {
            double outvalue = 0;
            return double.TryParse(val, out outvalue);
        }

        /// <summary>
        /// 是否是日期
        /// </summary>
        /// <param name="val">yyyyMMdd</param>
        /// <returns>是否</returns>
        public static bool IsDate(string val)
        {
            try
            {
                if (val.Length == 8)
                    DateTime.ParseExact(val, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
                else if (val.Length == 19)
                    DateTime.ParseExact(val, "yyyy-MM-dd HH:mm:ss", System.Globalization.CultureInfo.CurrentCulture);
                else
                    return false;
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 把yyyyMMddHHmmss字符串转换为DateTime
        /// </summary>
        /// <param name="value">yyyyMMddHHmmss字符串</param>
        /// <returns>日期对象</returns>
        public static DateTime StrToDataTime(string value)
        {
            return StrToDataTime(value, DateTime.Now);
        }

        /// <summary>
        /// 把yyyyMMddHHmmss或TODAY等开头的字符串串转换为DateTime
        /// </summary>
        /// <param name="value">yyyyMMddHHmmss或TODAY等开头的字符串</param>
        /// <param name="stdtime">基准时间</param>
        /// <returns>日期对象</returns>
        public static DateTime StrToDataTime(string value, DateTime stdtime)
        {
            DateTime dt = stdtime;
            if (IsInt(value))
            {
                int year = 1;
                int month = 1;
                int day = 1;
                int hour = 0;
                int minute = 0;
                int second = 0;
                if (value.Length >= 4)
                    int.TryParse(value.Substring(0, 4), out year);
                if (value.Length >= 6)
                    int.TryParse(value.Substring(4, 2), out month);
                if (value.Length >= 8)
                    int.TryParse(value.Substring(6, 2), out day);
                if (value.Length >= 10)
                    int.TryParse(value.Substring(8, 2), out hour);
                if (value.Length >= 12)
                    int.TryParse(value.Substring(10, 2), out minute);
                if (value.Length >= 14)
                    int.TryParse(value.Substring(12, 2), out second);
                dt = new DateTime(year, month, day, hour, minute, second);
            }
            else if (value.StartsWith("TODAY"))
            {
                double d = 0;
                double.TryParse(value.Substring(5), out d);
                dt = dt.AddDays(d);
            }
            else if (value.StartsWith("TRADEDAY"))
            {
                double d = 0;
                double.TryParse(value.Substring(8), out d);
                string trade_date = TradeDays.GetTradeDate(d, stdtime);
                if (trade_date != null)
                {
                    dt = DateTime.ParseExact(trade_date, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
                }
                else
                {
                    double iadd = (d > 0 ? 1 : -1);
                    while (true)
                    {
                        if (d <= -1 || d >= 1)
                        {
                            dt = dt.AddDays(iadd);
                            d -= iadd;
                            if (dt.DayOfWeek.Equals(DayOfWeek.Saturday))
                            {
                                dt = dt.AddDays(iadd);
                                if (iadd > 0) dt = dt.AddDays(iadd);
                            }
                            else if (dt.DayOfWeek.Equals(DayOfWeek.Sunday))
                            {
                                dt = dt.AddDays(iadd);
                                if (iadd < 0) dt = dt.AddDays(iadd);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            else if (value.StartsWith("MONTH"))
            {
                int d = 0;
                int.TryParse(value.Substring(5), out d);
                if (d == 0 && value.Substring(5, 1).Equals("-"))
                    dt = dt.AddDays(-1);
                dt = dt.AddMonths(d);
                dt = dt.AddDays(1 - dt.Day);
            }
            else if (value.StartsWith("YEAR"))
            {
                int d = 0;
                int.TryParse(value.Substring(4), out d);
                if (d == 0 && value.Substring(4, 1).Equals("-"))
                    dt = dt.AddMonths(-1);
                dt = dt.AddYears(d);
                dt = dt.AddMonths(1 - dt.Month);
                dt = dt.AddDays(1 - dt.Day);
            }
            return dt;
        }

        /// <summary>
        /// 关键字替换
        /// </summary>
        /// <param name="val">原字符串</param>
        /// <param name="tradedate">日期</param>
        /// <returns>替换后的字符串</returns>
        public static string ReplaceWord(string val, string tradedate)
        {
            DateTime dt = StrToDataTime(tradedate);
            string ret = val.Replace("[yyyymmdd]", dt.ToString("yyyyMMdd"));
            ret = ret.Replace("[YYYYMMDD]", dt.ToString("yyyyMMdd"));
            ret = ret.Replace("YYYYMMDD", dt.ToString("yyyyMMdd"));
            ret = ret.Replace("[YYMMDD]", dt.ToString("yyMMdd"));
            ret = ret.Replace("[YYYYMM]", dt.ToString("yyyyMM"));
            ret = ret.Replace("[MMDD]", dt.ToString("MMdd"));
            ret = ret.Replace("[ADD]", int.Parse(dt.ToString("MM")).ToString("x") + dt.ToString("dd"));
            ret = ret.Replace("[YYYY-MM-DD]", dt.ToString("yyyy-MM-dd"));
            ret = ret.Replace("[YYYY-M-D]", dt.ToString("yyyy-M-d"));
            ret = ret.Replace("[YYYY-MM-D]", dt.ToString("yyyy-MM-d"));
            ret = ret.Replace("[YYYY-M-DD]", dt.ToString("yyyy-M-dd"));
            ret = ret.Replace("[YYYY]", dt.ToString("yyyy"));
            ret = ret.Replace("[WWWW]", ((int)dt.DayOfWeek).ToString());
            ret = ret.Replace("[JJJJ]", ((dt.Ticks / 10000000 / 3600 / 24) % 2).ToString());
            string PATTERN = "[[](?<DATE_EXP>.*?)[]]";
            System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(PATTERN, System.Text.RegularExpressions.RegexOptions.Multiline);
            System.Text.RegularExpressions.Match match = regex.Match(ret);
            while (match.Success)
            {
                string svalue = match.Groups["DATE_EXP"].Value;
                string dvalue = "";
                if (svalue.StartsWith("TODAY") || svalue.StartsWith("TRADEDAY"))
                    dvalue = Funcs.StrToDataTime(svalue, dt).ToString("yyyyMMdd");
                else if (svalue.StartsWith("MONTH"))
                    dvalue = Funcs.StrToDataTime(svalue, dt).ToString("yyyyMM");
                else if (svalue.StartsWith("YEAR"))
                    dvalue = Funcs.StrToDataTime(svalue, dt).ToString("yyyy");
                if (dvalue.Length > 0)
                    ret = ret.Replace("[" + svalue + "]", dvalue);
                match = match.NextMatch();
            }
            return ret;
        }


        /// <summary>
        /// 检测时间是否已到
        /// </summary>
        /// <param name="tradedate">日期</param>
        /// <param name="tradetime">时间</param>
        public static bool CheckTime(string tradedate, string tradetime)
        {
            DateTime dtm = Funcs.StrToDataTime(tradedate + tradetime.Replace("-", "").Replace(":", ""));
            if (tradetime.StartsWith("-"))
                dtm = dtm.AddDays(1);
            if (DateTime.Now.CompareTo(dtm) > 0)
                return true;
            else
                return false;
        }

        /// <summary>
        /// 获取资源文件路径
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>文件路径</returns>
        public static string GetResourceFile(string filename)
        {
            return AppPath + "Resources" + System.IO.Path.DirectorySeparatorChar.ToString() + filename;
        }

        /// <summary>
        /// 获取Resources目录下的图片资源文件
        /// </summary>
        /// <param name="name">文件名</param>
        /// <returns>图片对象</returns>
        public static System.Drawing.Bitmap GetImage(String name)
        {
            String filename = GetResourceFile(name);
            if (System.IO.File.Exists(filename))
            {
                System.Drawing.Bitmap obj = new System.Drawing.Bitmap(filename);
                return obj;
            }
            else
            {
                return null;
            }
        }

        // <summary>
        /// 获取Resources目录下的图片资源文件
        /// </summary>
        /// <param name="name">文件名</param>
        /// <param name="width">图片宽度</param>
        /// <param name="height">图片高度</param>
        /// <returns>图片对象</returns>
        public static System.Drawing.Bitmap GetImage(String name, int width, int height)
        {
            String filename = GetResourceFile(name);
            if (System.IO.File.Exists(filename))
            {
                System.Drawing.Bitmap obj = new System.Drawing.Bitmap(filename);
                obj = (System.Drawing.Bitmap)obj.GetThumbnailImage(width, height, null, IntPtr.Zero);
                return obj;
            }
            else
            {
                return null;
            }
        }



        /// <summary>
        /// 返回已转换为指定形式的字符串
        /// </summary>
        /// <param name="str">要转换的 String 表达式</param>
        /// <returns>返回已转换为指定形式的字符串</returns>
        public static string StrConv(string str)
        {
            return Microsoft.VisualBasic.Strings.StrConv(str, (Microsoft.VisualBasic.VbStrConv)Conversion, 1033);
        }

        /// <summary>
        /// 控件的字符串转换
        /// </summary>
        /// <param name="ctrl">要转换的控件</param>
        public static void ControlStrConv(Control ctrl)
        {
            if (ctrl is ComboBox)
            {
                ComboBox comb = (ComboBox)ctrl;
                for (int i = 0; i < comb.Items.Count; i++)
                {
                    if (comb.Items[i] is System.Data.DataRowView)
                    {
                        System.Data.DataRowView drv = (System.Data.DataRowView)comb.Items[i];
                        string disname = comb.DisplayMember;
                        if (disname.Length > 0)
                        {
                            string newtext = StrConv(drv[disname].ToString());
                            if (!newtext.Equals(drv[disname].ToString())) drv.Row[disname] = newtext;
                        }
                    }
                }
            }
            else if (ctrl is ListBox)
            {
                ListBox comb = (ListBox)ctrl;
                for (int i = 0; i < comb.Items.Count; i++)
                {
                    if (comb.Items[i] is System.Data.DataRowView)
                    {
                        System.Data.DataRowView drv = (System.Data.DataRowView)comb.Items[i];
                        string disname = comb.DisplayMember;
                        if (disname.Length > 0)
                        {
                            string newtext = StrConv(drv[disname].ToString());
                            if (!newtext.Equals(drv[disname].ToString()))
                            {
                                drv.Row[disname] = newtext;
                            }
                        }
                    }
                    else if (comb.Items[i] is DictElement)
                    {
                        DictElement dict = (DictElement)comb.Items[i];
                        string newtext = StrConv(dict.Text);
                        if (!newtext.Equals(dict.Text))
                        {
                            dict.Text = newtext;
                            comb.Items[i] = dict;
                        }
                    }
                }
            }
            else if (ctrl is ToolStrip)
            {
                ToolStrip tool = (ToolStrip)ctrl;
                foreach (ToolStripItem tsi in tool.Items)
                {
                    ControlStrConv(tsi);
                }
            }
            else if (ctrl is TreeView)
            {
                TreeView tree = (TreeView)ctrl;
                foreach (TreeNode node in tree.Nodes)
                {
                    ControlStrConv(node);
                }
            }
            else if (ctrl is DataGridView)
            {
                DataGridView dgv = (DataGridView)ctrl;
                foreach (DataGridViewColumn tsi in dgv.Columns)
                {
                    string newtext = StrConv(tsi.HeaderText);
                    if (!newtext.Equals(tsi.HeaderText)) tsi.HeaderText = newtext;
                }
            }
            else if (!(ctrl is TextBox))
            {
                string newtext = StrConv(ctrl.Text);
                if (!newtext.Equals(ctrl.Text)) ctrl.Text = newtext;
                foreach (Control sub_ctrl in ctrl.Controls)
                {
                    ControlStrConv(sub_ctrl);
                }
            }
        }

        private static void ControlStrConv(ToolStripItem tsi)
        {
            string newtext = StrConv(tsi.Text);
            if (!newtext.Equals(tsi.Text)) tsi.Text = newtext;
            newtext = StrConv(tsi.ToolTipText);
            if (!newtext.Equals(tsi.ToolTipText)) tsi.ToolTipText = newtext;
            if (tsi is ToolStripDropDownItem)
            {
                ToolStripDropDownItem tsmi = (ToolStripDropDownItem)tsi;
                foreach (ToolStripItem sub_tsi in tsmi.DropDownItems)
                {
                    ControlStrConv(sub_tsi);
                }
            }
        }

        private static void ControlStrConv(TreeNode node)
        {
            string newtext = StrConv(node.Text);
            if (!newtext.Equals(node.Text)) node.Text = newtext;
            foreach (TreeNode sub_node in node.Nodes)
            {
                ControlStrConv(sub_node);
            }
        }
    }
}
